package cn.tedu.sy;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author ：Ds
 * @date ：2021/11/22 9:33
 * Describe ：该类用于复习多线程实现编程方案二：实现Runnable
 */
public class TestRunnable01 {
    public static void main(String[] args) {
        Runnable r = new Runnable1();
//        Thread t1=new Thread(r);
//        Thread t2=new Thread(r);
//        Thread t3=new Thread(r);
//        Thread t4 = new Thread(r);
//        t1.start();
//        t2.start();
//        t3.start();
//        t4.start();
        /*Executors是用来创建线程池的工具类
        * 用法是：newFixedThreadPool（int）：这个方法用来创建指定书目的线程池对象
        * 创建处理的线程池对象ExecutorService：用来储存线程的池子，负责：新建/启动/关闭.... */
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            /*execute()让线程池安排线程来执行任务，每次都会安排一个线程来干活
            注意：这里的干活是指将线程列入就绪对象，具体执行那个看操作系统*/
            pool.execute(r);
        }
    }
}
/*1.出现安全问题的前提：多线程语句+有共享数据+多项操作语句共享数据
* 2.同步锁：相当于给容易出现问题的代码加锁，包裹所有出现的问题的代码
* 加锁之后，就有了同步的效果
* 但是加锁范围不能太大，干撒都排队，效率低；范围太小，锁不住，有安全隐患*/
class Runnable1 implements Runnable {
     int ticket = 100;
    @Override
    public void run() {
        Object o=new Object();
        while (true){
            /*同步锁代码块synchronize（唯一的锁对象）{会出现安全隐患的代码}
            * 同步代码块可以保证在同一时刻，同一资源只会被同一线程独享*/
            //synchronized(new Object()){//每次来都会new一个新线程，都会new一把新锁，锁不唯一
            //synchronized(Runnable1.class){
           synchronized (o){
                try{
                  Thread.sleep(10);
                }catch (Exception e){
                    e.printStackTrace();
                }
                //System.out.println(new Thread().getName() + "=" + ticket--);//会出现错误
               if(ticket>0){
                   System.out.println(Thread.currentThread().getName() + "=" + ticket--);
               }
               if(ticket<=0)break;
            }
        }
    }
}